package base

import (
	"gfrest/pkg/empty"

	"gfrest/common/code"
	"strconv"
	"strings"

	"github.com/gogf/gf/net/ghttp"
)

// Controller Controller
type Controller struct {
}

// Result Result
type Result struct {
	Code    int         `json:"code"`
	Message string      `json:"message"`
	Data    interface{} `json:"data"`
}

// PageData PageData
type PageData struct {
	Count     int
	Page      int
	TotalPage int
	PageSize  int
}

// PagedResult PagedResult
type PagedResult struct {
	Result
	PageData
}

// InitPageData InitPageData
func InitPageData(count, page, pageSize int) PageData {
	var p = PageData{
		Count:    count,
		Page:     page,
		PageSize: pageSize,
	}
	if p.PageSize <= 0 {
		p.PageSize = 10
	}
	p.TotalPage = p.Count / p.PageSize
	return p
}

// Response API返回
func Response(r *ghttp.Request, rs Result) {
	if rs.Code < 600 && rs.Code > 0 {
		r.Response.Status = int(rs.Code)
	} else {
		r.Response.Status = 400
	}
	_ = r.Response.WriteJsonExit(rs)

}

// SuccessResponse API返回
func SuccessResponse(r *ghttp.Request, rs interface{}) {
	_ = r.Response.WriteJsonExit(rs)
}

// Success 返回成功
func Success(r *ghttp.Request, data interface{}) {
	Response(r, Result{Code: code.RESPONSE_SUCCESS, Message: "success", Data: data})
}

// SuccessPaged 返回成功
func SuccessPaged(r *ghttp.Request, data interface{}, pageData PageData) {

	SuccessResponse(r, PagedResult{
		Result{Code: 0, Message: "success", Data: data},
		pageData,
	})
}

// Fail 返回失败
func Fail(r *ghttp.Request, errInfo code.Error, Data ...interface{}) {
	errCode, msg := errInfo.Code, errInfo.Message
	if msg == "" {
		msg = "fail"
	}
	if len(Data) > 0 {
		Response(r, Result{Code: errCode, Message: msg, Data: Data[0]})
	} else {
		Response(r, Result{Code: errCode, Message: msg})
	}
}

// funcName 获取当前用户
//
//func GetUser(r *ghttp.Request) *model.GadminUser {
//	claims := jwt.ExtractClaims(r)
//	user, _ := model.GetUserByName(claims["username"].(string))
//	return user
//}
//
//func GetUserID(r *ghttp.Request) int {
//	addu := GetUser(r)
//	var addUserId = 0
//	if addu != nil {
//		addUserId = addu.Id
//	}
//	return addUserId
//}

var (
	suffContains  = "__contains"
	suffIcontains = "__icontains"
	suffRange     = "__range"
	suffIN        = "__in"
	suffGTE       = "__gte"
	suffLTE       = "__lte"
	suffGT        = "__gt"
	suffLT        = "__lt"
)
var filterKeys = []string{
	suffContains,
	suffIcontains,
	suffRange,
	suffIN,
	suffGTE,
	suffLTE,
	suffGT,
	suffLT,
}
var filterMap = map[string]string{
	suffContains:  " like BINARY ? ",
	suffIcontains: " like ? ",
	suffRange:     " between ? AND ? ",
	suffIN:        " in (?) ",
	suffGTE:       " >= ? ",
	suffLTE:       " <= ? ",
	suffGT:        " > ? ",
	suffLT:        " < ? ",
}

// getWhereFromRequest getWhereFromRequest
func getWhereFromRequest(querys map[string]interface{}) map[string]interface{} {
	wheres := make(map[string]interface{}, 0)
	for key := range querys {
		val := querys[key]
		Got := 0
		for _, kk := range filterKeys {
			if strings.Contains(key, kk) {
				Got = 1
				if _, ok := querys[key].(string); ok {
					if suffContains == kk || suffIcontains == kk {
						val = "%" + querys[key].(string) + "%"
					}
					if suffRange == kk || suffIN == kk {
						val = strings.Split(querys[key].(string), ",")
					}
				}

				wheres[key[0:len(key)-len(kk)]+filterMap[kk]] = val
				break
			}
		}
		if Got == 0 && !empty.IsEmpty(val) {
			wheres[key] = val

		}
	}
	return wheres
}

// GetWhereFromRequest GetWhereFromRequest
func GetWhereFromRequest(r *ghttp.Request, strKeys, intKeys, searchKeys []string) map[string]interface{} {
	retQuery := make(map[string]interface{}, 0)
	query := r.GetQueryMap()
	if strKeys != nil {

		for _, key := range strKeys {
			if item, ok := query[key]; ok {
				retQuery[key] = item
			}
		}
	}
	if intKeys != nil {
		for _, key := range intKeys {
			if item, ok := query[key]; ok {
				if strings.Contains(key, suffRange) || strings.Contains(key, suffIN) {
					items := strings.Split(item.(string), ",")
					if len(items) == 2 {
						ii, _ := strconv.Atoi(items[0])
						jj, _ := strconv.Atoi(items[1])
						retQuery[key] = []int{ii, jj}
					}
				} else {
					ii, _ := strconv.Atoi(item.(string))
					retQuery[key] = ii

				}
			}
		}
	}
	retWhere := getWhereFromRequest(retQuery)

	if item, ok := query["search"]; ok && searchKeys != nil {
		searchKey := make([]string, 0)
		searchValue := make([]interface{}, 0)
		for _, key := range searchKeys {
			searchKey = append(searchKey, key+" like ? ")
			searchValue = append(searchValue, "%"+item.(string)+"%")
		}
		retWhere[strings.Join(searchKey, " or ")] = searchValue
	}
	return retWhere
}
